﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using System.Xml.Serialization;

namespace Qpm.Automap.Core.UI
{
  public partial class ContractInfoPage : Wizard.UI.InternalWizardPage
  {
    public ContractInfoPage()
    {
      InitializeComponent();
      this.Banner.Title = "Step 2 of 4 - Contract Information";
      this.Banner.Subtitle = "Enter Contract Information for project: "+ parameters.projectName;
    }

    private void ContractInfoPage_SetActive(object sender, CancelEventArgs e)
    {
      this.Anchor = AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom;
      this.Size = this.Parent.Size;
      if (dgv_contractInfo.DataSource == null)
      {
        populateContractInfoTable();
        //dgv_contractInfo.DataSource = parameters.contractInfo;

      }
      SetWizardButtons(Wizard.UI.WizardButtons.Back | Wizard.UI.WizardButtons.Next);
    }

    private void ContractInfoPage_WizardNext(object sender, Wizard.UI.WizardPageEventArgs e)
    {
        DataTable contractTable = new DataTable();
        contractTable.Columns.Add("FieldName", typeof(string));
        contractTable.Columns.Add("Value", typeof(string));
        contractTable.Columns.Add("NodeName", typeof(string));
        contractTable.Columns.Add("ParentNode", typeof(string));
        contractTable.Columns.Add("DataType", typeof(string));
        for (int i = 0; i < dgv_contractInfo.Rows.Count; i++)
        {
            DataRow row = contractTable.NewRow();
            row[0] = dgv_contractInfo.Rows[i].Cells[0].Value.ToString();
            row[2] = dgv_contractInfo.Rows[i].Cells[2].Value.ToString();
            row[3] = dgv_contractInfo.Rows[i].Cells[3].Value.ToString();
            row[4] = dgv_contractInfo.Rows[i].Cells[4].Value.ToString();
            if (row[4].ToString() == "ProjectPeriod")
            {
                DataGridViewLinkCell lCell = dgv_contractInfo.Rows[i].Cells[1] as DataGridViewLinkCell;
                if (lCell.Tag != null)
                {
                    ProjectPeriodFormParams p = (ProjectPeriodFormParams)lCell.Tag;
                    if (p.ProjectPeriod != null)
                    {
                        StringWriter sw = new StringWriter();
                        XmlSerializer xs = new XmlSerializer(typeof(ProjectPeriodType));
                        xs.Serialize(sw, p.ProjectPeriod);
                        row[1] = sw.ToString();
                    }
                }
            }
            else
            {
                if (dgv_contractInfo.Rows[i].Cells[1].Value != null)
                    row[1] = dgv_contractInfo.Rows[i].Cells[1].Value.ToString();
            }
            contractTable.Rows.Add(row);
        }
        parameters.contractInfo = contractTable;
    }

    private void populateContractInfoTable()
    {
        dgv_contractInfo.Rows.Clear();
        dgv_contractInfo.Columns.Clear();

      XmlDocument fieldsDoc = new XmlDocument();
      fieldsDoc.Load(parameters.projectContractFile);

      dgv_contractInfo.Columns.Add("FieldName", "Field Name");
      dgv_contractInfo.Columns.Add("Value", "Value");
      dgv_contractInfo.Columns.Add("NodeName", "NodeName");
      dgv_contractInfo.Columns.Add("ParentNode", "ParentNode");
      dgv_contractInfo.Columns.Add("DataType", "DataType");
      dgv_contractInfo.Columns[0].ReadOnly = true;
      dgv_contractInfo.Columns[0].DefaultCellStyle.BackColor =
      dgv_contractInfo.Columns[0].DefaultCellStyle.SelectionBackColor = Color.LightGray;
      dgv_contractInfo.Columns[0].DefaultCellStyle.SelectionBackColor =
      dgv_contractInfo.Columns[0].DefaultCellStyle.ForeColor;
      dgv_contractInfo.Columns[2].Visible = false;
      dgv_contractInfo.Columns[3].Visible = false;
      dgv_contractInfo.Columns[4].Visible = false;

      XmlNodeList fieldNodes = fieldsDoc.SelectNodes("//ContractFields/Field");

      bool configExists = false;
      XmlDocument configDoc = new XmlDocument();
      if (File.Exists(parameters.configFile))
      {
        configExists = true;
        configDoc.Load(parameters.configFile);
      }

      foreach (XmlElement fieldNode in fieldNodes)
      {
        string fieldName = fieldNode.Attributes["Name"].Value;
        string nodeName = "";
        if (fieldNode.Attributes["NodeName"] != null)
        {
            nodeName = fieldNode.Attributes["NodeName"].Value;
        }
        string parentNode = "";
        if (fieldNode.Attributes["ParentNode"] != null)
        {
            parentNode = fieldNode.Attributes["ParentNode"].Value;
        }
        string fieldType = "";
        if (fieldNode.Attributes["DataType"] != null)
        {
            fieldType = fieldNode.Attributes["DataType"].Value;
        }
        string fieldValue = "";

        if (configExists)
        {
          XmlNode contractNode = configDoc.SelectSingleNode("//ContractInfo/Field[@Name='" + fieldName + "']");
          fieldValue = contractNode == null ? string.Empty : contractNode.InnerText;
        }
        dgv_contractInfo.Rows.Add(new object[] { fieldName, fieldValue, nodeName, parentNode, fieldType });
        XmlNodeList options = fieldNode.SelectNodes("Options/Option");
        if (options.Count > 0)
        {
            DataGridViewComboBoxCell newCell = new DataGridViewComboBoxCell();
            foreach (XmlNode optionNode in options)
            {
                newCell.Items.Add(optionNode.InnerText);
            }
            if (newCell.Items.Contains(fieldValue))
                newCell.Value = fieldValue;
            dgv_contractInfo.Rows[dgv_contractInfo.Rows.Count - 1].Cells[1] = newCell;
        }
        switch (fieldType)
        {
            case "Date":
                DataGridViewButtonCell bCell = new DataGridViewButtonCell();
                if (fieldValue!=string.Empty)
                    bCell.Value = DateTime.Parse(fieldValue).ToShortDateString();
                dgv_contractInfo.Rows[dgv_contractInfo.Rows.Count - 1].Cells[1] = bCell;
                break;
            case "ProjectPeriod":
                DataGridViewLinkCell lCell = new DataGridViewLinkCell();
                string cellValue = "Click to set project period"; 
                lCell.Tag = GetProjectPeriodParameters(fieldName, fieldValue, ref cellValue);
                lCell.Value = cellValue;
                dgv_contractInfo.Rows[dgv_contractInfo.Rows.Count - 1].Cells[1] = lCell;
                dgv_contractInfo.Rows[dgv_contractInfo.Rows.Count - 1].Cells[4].Tag = fieldName;
                break;
            default:
                break;
        }

      }
      dgv_contractInfo.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
      dgv_contractInfo.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    }

    private static ProjectPeriodFormParams GetProjectPeriodParameters(string fieldName, string fieldValue, ref string cellValue)
    {
        ProjectPeriodFormParams p = new ProjectPeriodFormParams();
        if (fieldValue == string.Empty)
        {
            return null;
        }
        else
        {
            StringReader sr = new StringReader(fieldValue);
            XmlSerializer xs = new XmlSerializer(typeof(ProjectPeriodType));
            object obj = xs.Deserialize(sr);
            if (obj != null)
            {
                ProjectPeriodType period = obj as ProjectPeriodType;
                p.ProjectPeriod = period;
                cellValue = p.ProjectPeriod.StartDateTime + " to " + p.ProjectPeriod.EndDateTime;
            }
            else
            {
                return null;
            }
        } 
        SetProjectPeriod(fieldName, p);
        return p;
    }

    private static void SetProjectPeriod(string fieldName, ProjectPeriodFormParams p)
    {

        switch (fieldName)
        {
            case "F1 Current Period":
                p.IsNameReadOnly = true;
                p.UseDuration = false;
                p.ProjectPeriod.Name = new TextType("CUR");
                p.ProjectPeriod.SequenceNumeric = 1;
                break;
            case "F1 Cum to Date":
                p.IsNameReadOnly = true;
                p.UseDuration = false;
                p.ProjectPeriod.Name = new TextType("CUM");
                p.ProjectPeriod.SequenceNumeric = 2;
                break;
            case "F1 At Complete":
                p.IsNameReadOnly = true;
                p.UseDuration = false;
                p.ProjectPeriod.Name = new TextType("ATC");
                p.ProjectPeriod.SequenceNumeric = 3;
                break;
            case "F3 Cum to Date BOP":
                p.IsNameReadOnly = true;
                p.UseDuration = false;
                p.ProjectPeriod.Name = new TextType("CUMBOP");
                p.ProjectPeriod.SequenceNumeric = 1;
                break;
            case "F3 Cum to Date EOP":
                p.IsNameReadOnly = true;
                p.UseDuration = false;
                p.ProjectPeriod.Name = new TextType("CUMEOP");
                p.ProjectPeriod.SequenceNumeric = 2;
                break;
            case "F3 Current Period BOP":
                p.IsNameReadOnly = true;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("CURBOP");
                p.ProjectPeriod.SequenceNumeric = 3;
                break;
            case "F3 Forecast Month 1":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 4;
                break;
            case "F3 Forecast Month 2":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 5;
                break;
            case "F3 Forecast Month 3":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 6;
                break;
            case "F3 Forecast Month 4":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 7;
                break;
            case "F3 Forecast Month 5":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 8;
                break;
            case "F3 Forecast Month 6":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 9;
                break;
            case "F3 Out Year 1":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.QH;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 10;
                break;
            case "F3 Out Year 2":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.QH;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 11;
                break;
            case "F3 Out Year 3":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.QH;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 12;
                break;
            case "F3 To Complete":
                p.IsNameReadOnly = true;
                p.UseDuration = false;
                p.ProjectPeriod.Name = new TextType("TC");
                p.ProjectPeriod.SequenceNumeric = 12;
                break;
            case "F4 Current Period":
                p.IsNameReadOnly = true;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("CUR");
                p.ProjectPeriod.SequenceNumeric = 1;
                break;
            case "F4 Cum to Date":
                p.IsNameReadOnly = true;
                p.UseDuration = false;
                p.ProjectPeriod.Name = new TextType("CUM");
                p.ProjectPeriod.SequenceNumeric = 2;
                break;
            case "F4 Forecast Month 1":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 3;
                break;
            case "F4 Forecast Month 2":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 4;
                break;
            case "F4 Forecast Month 3":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 5;
                break;
            case "F4 Forecast Month 4":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 6;
                break;
            case "F4 Forecast Month 5":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 7;
                break;
            case "F4 Forecast Month 6":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.MON;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 8;
                break;
            case "F4 Out Year 1":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.QH;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 9;
                break;
            case "F4 Out Year 2":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.QH;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 10;
                break;
            case "F4 Out Year 3":
                p.IsNameReadOnly = false;
                p.UseDuration = true;
                p.ProjectPeriod.DurationMeasure = new DurationMeasureType();
                p.ProjectPeriod.DurationMeasure.unitCode = MeasurementUnitCommonCodeDurationContentType.QH;
                p.ProjectPeriod.Name = new TextType("");
                p.ProjectPeriod.SequenceNumeric = 11;
                break;
            case "F4 To Complete":
                p.IsNameReadOnly = true;
                p.UseDuration = false;
                p.ProjectPeriod.Name = new TextType("TC");
                p.ProjectPeriod.SequenceNumeric = 12;
                break;
            default:
                break;
        }
    }

    private void dgv_contractInfo_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex < 0 || e.ColumnIndex < 0)
            return;
        if (dgv_contractInfo.Rows[e.RowIndex].Cells[e.ColumnIndex].GetType() == typeof(DataGridViewButtonCell))
        {
            DataGridViewButtonCell cell = dgv_contractInfo.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewButtonCell;
            CustomDatePicker picker = new CustomDatePicker();
            if (cell.Value!=null && cell.Value.ToString() != string.Empty)
                picker.SelectedDate = DateTime.Parse(cell.Value.ToString());
            picker.ShowDialog();
            if (picker.SelectedDate != null)
                cell.Value = picker.SelectedDate.ToString("s");
        }
    }

    private void dgv_contractInfo_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex < 0 || e.ColumnIndex < 0)
            return;
        if (dgv_contractInfo.Rows[e.RowIndex].Cells[e.ColumnIndex].GetType() == typeof(DataGridViewLinkCell))
        {
            DataGridViewLinkCell cell = dgv_contractInfo.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewLinkCell;
            ProjectPeriodForm picker = new ProjectPeriodForm();
            ProjectPeriodFormParams p = new ProjectPeriodFormParams();
            if (cell.Tag != null)
            {
                p = (ProjectPeriodFormParams)cell.Tag;
            }
            else
            {
                string fieldName = dgv_contractInfo.Rows[e.RowIndex].Cells[4].Tag.ToString();
                p.ProjectPeriod = new ProjectPeriodType();
                p.ProjectPeriod.Description = new TextType(fieldName.Remove(0, 3));
                p.ProjectPeriod.StartDateTime = DateTime.Today.ToString("s");
                p.ProjectPeriod.EndDateTime = DateTime.Today.ToString("s");
                SetProjectPeriod(fieldName, p);
            }
            picker.ProjectPeriod = p.ProjectPeriod;
            picker.IsNameReadOnly = p.IsNameReadOnly;
            picker.UseDuration = p.UseDuration;
            picker.ShowDialog();
            if (picker.ProjectPeriod == null)
            {
                cell.Value = "Click to enter project period";
                cell.Tag = null;
            }
            else
            {
                cell.Value = picker.ProjectPeriod.StartDateTime + " to " + picker.ProjectPeriod.EndDateTime;
                cell.Tag = new ProjectPeriodFormParams(picker.ProjectPeriod, picker.IsNameReadOnly, picker.UseDuration);
            }
        }
    }
  }
}
